package com.feonix.common.util.xml;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.converters.ErrorReporter;
import com.thoughtworks.xstream.converters.ErrorWriter;
import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;
import com.thoughtworks.xstream.core.JVM;
import com.thoughtworks.xstream.core.util.ThreadSafeSimpleDateFormat;

public class XmlDateConverter extends AbstractSingleValueConverter implements ErrorReporter {

	private static final String[] localArray;
	private static final String defaultFormat;
	private static final String defaultEraFormat;
	private static final TimeZone timeZone = TimeZone.getDefault();
	private static final long localCalenderTime;
	private final ThreadSafeSimpleDateFormat safeSimpleDateFormat1;
	private final ThreadSafeSimpleDateFormat safeSimpleDateFormat2;
	private final ThreadSafeSimpleDateFormat[] acceptableFormats;
	static {
		String str1 = "yyyy-MM-dd HH:mm:ss.S z";
		String str2 = "yyyy-MM-dd G HH:mm:ss.S z";
		ArrayList<String> arrayList = new ArrayList<String>();
		boolean bool = JVM.canParseUTCDateFormat();
		defaultFormat = (bool) ? "yyyy-MM-dd HH:mm:ss.S z" : "yyyy-MM-dd HH:mm:ss.S 'UTC'";
		defaultEraFormat = (bool) ? "yyyy-MM-dd G HH:mm:ss.S z" : "yyyy-MM-dd G HH:mm:ss.S 'UTC'";
		arrayList.add("yyyy-MM-dd HH:mm:ss.S z");
		if (!(bool)) {
			arrayList.add("yyyy-MM-dd HH:mm:ss.S z");
		}
		arrayList.add("yyyy-MM-dd");
		arrayList.add("yyyy-MM-dd HH:mm:ss");
		arrayList.add("yyyy-MM-dd HH:mm");
		arrayList.add("HH:mm:ss");
		arrayList.add("HH:mm");
		arrayList.add("yyyy-MM-dd HH:mm:ss.S a");

		arrayList.add("yyyy-MM-dd HH:mm:ssz");
		arrayList.add("yyyy-MM-dd HH:mm:ss z");
		if (!(bool)) {
			arrayList.add("yyyy-MM-dd HH:mm:ss 'UTC'");
		}

		arrayList.add("yyyy-MM-dd HH:mm:ssa");
		localArray = arrayList.toArray(new String[arrayList.size()]);

		Calendar calendar = Calendar.getInstance();
		calendar.setTimeZone(timeZone);
		calendar.clear();
		calendar.set(1, 0, 1);
		localCalenderTime = calendar.getTime().getTime();
	}

	public XmlDateConverter() {
		this(false);
	}

	public XmlDateConverter(TimeZone paramTimeZone) {
		this(defaultFormat, localArray, paramTimeZone);
	}

	public XmlDateConverter(boolean paramBoolean) {
		this(defaultFormat, localArray, paramBoolean);
	}

	public XmlDateConverter(String defaultFormat, String[] acceptableFormats) {
		this(defaultFormat, acceptableFormats, false);
	}

	public XmlDateConverter(String defaultFormat, String[] acceptableFormats, TimeZone paramTimeZone) {
		this(defaultFormat, acceptableFormats, paramTimeZone, false);
	}

	public XmlDateConverter(String defaultFormat, String[] acceptableFormats, boolean paramBoolean) {
		this(defaultFormat, acceptableFormats, timeZone, paramBoolean);
	}

	public XmlDateConverter(String defaultFormat, String[] acceptableFormats, TimeZone paramTimeZone,
			boolean paramBoolean) {
		this(defaultEraFormat, defaultFormat, acceptableFormats, Locale.ENGLISH, paramTimeZone, paramBoolean);
	}

	public XmlDateConverter(String defaultEraFormat, String defaultFormat, String[] acceptableFormats, Locale locale,
			TimeZone paramTimeZone, boolean lenient) {
		if (defaultEraFormat != null)
			this.safeSimpleDateFormat2 = new ThreadSafeSimpleDateFormat(defaultEraFormat, paramTimeZone, 4, 20,
					lenient);
		else {
			this.safeSimpleDateFormat2 = null;
		}
		this.safeSimpleDateFormat1 = new ThreadSafeSimpleDateFormat(defaultFormat, paramTimeZone, 4, 20, lenient);
		this.acceptableFormats = ((acceptableFormats != null) ? new ThreadSafeSimpleDateFormat[acceptableFormats.length]
				: new ThreadSafeSimpleDateFormat[0]);
		for (int j = 0; j < this.acceptableFormats.length; ++j)
			this.acceptableFormats[j] = new ThreadSafeSimpleDateFormat(acceptableFormats[j], paramTimeZone, 1, 20,
					lenient);
	}

	@Override
	public void appendErrors(ErrorWriter paramErrorWriter) {
		paramErrorWriter.add("Default date pattern", this.safeSimpleDateFormat1.toString());
		if (this.safeSimpleDateFormat2 != null) {
			paramErrorWriter.add("Default era date pattern", this.safeSimpleDateFormat2.toString());
		}
		for (int j = 0; j < this.acceptableFormats.length; ++j)
			paramErrorWriter.add("Alternative date pattern", this.acceptableFormats[j].toString());

	}

	@Override
	public boolean canConvert(Class paramClass) {
		return paramClass.equals(Date.class);
	}

	@Override
	public Object fromString(String paramString) {
		if (this.safeSimpleDateFormat2 != null) {
			try {
				return this.safeSimpleDateFormat2.parse(paramString);
			} catch (ParseException j) {
				if (this.safeSimpleDateFormat2 != this.safeSimpleDateFormat1)
					try {
						return this.safeSimpleDateFormat1.parse(paramString);
					} catch (ParseException parseException) {
						for (int k = 0; k < this.acceptableFormats.length; ++k) {
							try {
								return this.acceptableFormats[k].parse(paramString);
							} catch (ParseException localParseException3) {
							}
						}
						throw new ConversionException("Cannot parse date " + paramString);
					}
			}
		}
		return paramString;

	}

	public String toString(Object paramObject) {
		Date date = (Date) paramObject;
		if ((date.getTime() < localCalenderTime) && (this.safeSimpleDateFormat2 != null)) {
			return this.safeSimpleDateFormat2.format(date);
		}
		return this.safeSimpleDateFormat1.format(date);
	}

}
